package bicing;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.OutputStreamWriter;
import java.util.Date;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.cache.Cache;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;

import com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl;
import common.CacheSingleton;

@SuppressWarnings("serial")
public class BicingAbstractServlet extends HttpServlet {
	protected final Logger logger = Logger.getLogger(this.getClass().getPackage().getName());
	private TransformerFactory transformerFactory;
	private Fetcher fetcher;
	private KmlFixer fixer;
	private DocumentBuilder documentBuilder;
	private Cache cache;
	public static final String DATEKEY = "BicingDate";
	public static final String KMZKEY = "BicingKmz";
	
	@Override
	public final void init() throws ServletException {
		try {
			fetcher = new Fetcher();
			fixer = new KmlFixer();
			documentBuilder = DocumentBuilderFactoryImpl.newInstance().newDocumentBuilder();
			transformerFactory = TransformerFactory.newInstance();
			cache = CacheSingleton.getCache();
		} catch (Exception e) {
			throw new ServletException(e);
		}
	}
	
	@SuppressWarnings("unchecked")
	protected void cacheKmz(byte[] kmz){
		cache.put(KMZKEY, kmz);
		cache.put(DATEKEY, new Date(System.currentTimeMillis()));
		logger.info("Bicing KMZ updated");
	}
	
	public Date getKmzCacheDate(){
		return (Date) cache.get(DATEKEY);
	}
	
	protected byte[] getKmzFromCache(){
		return (byte[]) cache.get(KMZKEY);
	}
	
	protected byte[] grabKmz() throws Exception{
		byte[] kmlBytes = fetcher.getKml();
		Document kmlDocument = documentBuilder.parse( new ByteArrayInputStream(kmlBytes));
		fixer.fixKml(kmlDocument);
		DOMSource source = new DOMSource(kmlDocument);
        Transformer transformer = transformerFactory.newTransformer();
		transformer.setOutputProperty(OutputKeys.INDENT, "no");
		//This array stores the zip file
		ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
		ZipOutputStream out = new ZipOutputStream(byteStream);
		out.putNextEntry(new ZipEntry("document.kml"));
		transformer.transform(source, new StreamResult( new OutputStreamWriter(out, Fetcher.charset)));
        out.close();
        return byteStream.toByteArray();
	}
}
